<template>
  <div class="panel-tab__content">
    <div class="element-drawer__button">
      <el-tooltip class="item" effect="dark" content="添加任务监听器" placement="bottom">
        <el-button size="mini" type="text" icon="el-icon-plus" @click="openListenerForm(null)" />
      </el-tooltip>
    </div>
    <el-table :data="elementListenersList" size="mini" border>
      <el-table-column label="#" width="50px" type="index" />
      <el-table-column label="事件" align="center" prop="event" show-overflow-tooltip :formatter="row => listenerEventTypeObject[row.event]" />
      <el-table-column label="类型" header-align="center" show-overflow-tooltip :formatter="row => listenerTypeObject[row.listenerType]" />
      <el-table-column label="操作" width="60px" align="center">
        <template slot-scope="{ row, $index }">
          <el-button size="mini" type="text" @click="openListenerForm(row, $index)"><i class="el-icon-edit" /></el-button>
          <el-button size="mini" type="text" style="color: #ff4d4f" @click="removeListener(row, $index)"><i class="el-icon-delete" /></el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 监听器 编辑/创建 部分 -->
    <el-dialog :visible.sync="listenerFormModelVisible" :before-close="handleClose" width="600px" title="任务监听器" append-to-body destroy-on-close>
      <el-form ref="listenerFormRef" size="mini" :model="listenerForm" label-width="96px" @submit.native.prevent>
        <el-row :gutter="10">
          <el-col :span="12">
            <el-form-item label="事件类型" prop="event" :rules="{ required: true, message:'请选择事件类型', trigger: ['blur', 'change'] }">
              <el-select v-model="listenerForm.event" style="width:100%" placeholder="请选择事件类型">
                <el-option v-for="i in Object.keys(listenerEventTypeObject)" :key="i" :label="listenerEventTypeObject[i]" :value="i" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="监听器类型" prop="listenerType" :rules="{ required: true,message:'请选择监听器类型', trigger: ['blur', 'change'] }">
              <el-select v-model="listenerForm.listenerType" style="width:100%" placeholder="请选择监听器类型">
                <el-option v-for="i in Object.keys(listenerTypeObject)" :key="i" :label="listenerTypeObject[i]" :value="i" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>

        <!--<el-form-item label="监听器ID" prop="id" :rules="{ required: true, trigger: ['blur', 'change'] }">
          <el-input v-model="listenerForm.id" clearable />
        </el-form-item>-->

        <el-form-item
          v-if="listenerForm.listenerType === 'classListener'"
          key="listener-class"
          label="Java类"
          prop="class"
          :rules="{ required: true, message:'请填写Java类',trigger: ['blur', 'change'] }">
          <el-input v-model="listenerForm.class" clearable placeholder="请填写Java类" />
        </el-form-item>
        <el-form-item
          v-if="listenerForm.listenerType === 'expressionListener'"
          key="listener-expression"
          label="表达式"
          prop="expression"
          :rules="{ required: true, message:'请填写表达式',trigger: ['blur', 'change'] }">
          <el-input v-model="listenerForm.expression" clearable placeholder="请填写表达式" />
        </el-form-item>
        <el-form-item
          v-if="listenerForm.listenerType === 'delegateExpressionListener'"
          key="listener-delegate"
          label="代理表达式"
          prop="delegateExpression"
          :rules="{ required: true,message:'请填写代理表达式', trigger: ['blur', 'change'] }">
          <el-input v-model="listenerForm.delegateExpression" clearable placeholder="请填写代理表达式" />
        </el-form-item>
        <template v-if="listenerForm.listenerType === 'scriptListener'">
          <el-form-item
            key="listener-script-format"
            label="脚本格式"
            prop="scriptFormat"
            :rules="{ required: true, trigger: ['blur', 'change'], message: '请填写脚本格式' }">
            <el-input v-model="listenerForm.scriptFormat" clearable placeholder="请填写脚本格式" />
          </el-form-item>
          <el-form-item
            key="listener-script-type"
            label="脚本类型"
            prop="scriptType"
            :rules="{ required: true, trigger: ['blur', 'change'], message: '请选择脚本类型' }">
            <el-select v-model="listenerForm.scriptType" placeholder="请选择脚本类型" style="width:100%">
              <el-option label="内联脚本" value="inlineScript" />
              <el-option label="外部脚本" value="externalScript" />
            </el-select>
          </el-form-item>
          <el-form-item
            v-if="listenerForm.scriptType === 'inlineScript'"
            key="listener-script"
            label="脚本内容"
            prop="value"
            :rules="{ required: true, trigger: ['blur', 'change'], message: '请填写脚本内容' }">
            <el-input v-model="listenerForm.value" clearable placeholder="请填写脚本内容" />
          </el-form-item>
          <el-form-item
            v-if="listenerForm.scriptType === 'externalScript'"
            key="listener-resource"
            label="资源地址"
            prop="resource"
            :rules="{ required: true, trigger: ['blur', 'change'], message: '请填写资源地址' }">
            <el-input v-model="listenerForm.resource" clearable placeholder="请填写资源地址" />
          </el-form-item>
        </template>

        <template v-if="listenerForm.event === 'timeout'">
          <el-form-item key="eventDefinitionType" label="定时器类型" prop="eventDefinitionType">
            <el-select v-model="listenerForm.eventDefinitionType" placeholder="请选择定时器类型" style="width:100%">
              <el-option label="日期" value="date" />
              <el-option label="持续时长" value="duration" />
              <el-option label="循环" value="cycle" />
              <el-option label="无" value="null" />
            </el-select>
          </el-form-item>
          <el-form-item
            v-if="!!listenerForm.eventDefinitionType && listenerForm.eventDefinitionType !== 'null'"
            key="eventTimeDefinitions"
            label="定时器"
            prop="eventTimeDefinitions"
            :rules="{ required: true, trigger: ['blur', 'change'], message: '请填写定时器配置' }">
            <el-input v-model="listenerForm.eventTimeDefinitions" clearable placeholder="请填写定时器配置" />
          </el-form-item>
        </template>
      </el-form>
      <p class="listener-filed__title">
        <span><i class="el-icon-menu" style="margin-right:5px" />注入字段</span>
      </p>
      <div style="margin-bottom: 10px;">
        <el-button size="mini" type="primary" @click="openListenerFieldForm(null)">添加字段</el-button>
      </div>
      <el-table :data="fieldsListOfListener" size="mini" max-height="240" border fit style="flex: none">
        <el-table-column label="#" width="50px" type="index" />
        <el-table-column label="字段名称" min-width="100px" prop="name" />
        <el-table-column label="字段类型" min-width="80px" show-overflow-tooltip :formatter="row => fieldTypeObject[row.fieldType]" />
        <el-table-column label="字段值/表达式" min-width="100px" show-overflow-tooltip :formatter="row => row.string || row.expression" />
        <el-table-column label="操作" width="100px">
          <template slot-scope="{ row, $index }">
            <el-button size="mini" type="text" @click="openListenerFieldForm(row, $index)"><i class="el-icon-edit" /></el-button>
            <el-button size="mini" type="text" style="color: #ff4d4f" @click="removeListenerField(row, $index)"><i class="el-icon-delete" /></el-button>
          </template>
        </el-table-column>
      </el-table>

      <div slot="footer" class="dialog-footer">
        <el-button size="mini" @click="listenerFormModelVisible = false">取 消</el-button>
        <el-button size="mini" type="primary" @click="saveListenerConfig">保 存</el-button>
      </div>
    </el-dialog>

    <!-- 注入西段 编辑/创建 部分 -->
    <el-dialog title="字段配置" :visible.sync="listenerFieldFormModelVisible" :before-close="handleClose" width="600px" append-to-body destroy-on-close>
      <el-form ref="listenerFieldFormRef" :model="listenerFieldForm" size="mini" label-width="96px" style="height: 136px" @submit.native.prevent>
        <el-form-item label="字段名称：" prop="name" :rules="{ required: true,message: '请填写字段名称', trigger: ['blur', 'change'] }">
          <el-input v-model="listenerFieldForm.name" clearable placeholder="请填写字段名称" />
        </el-form-item>
        <el-form-item label="字段类型：" prop="fieldType" :rules="{ required: true, message: '请选择字段类型',trigger: ['blur', 'change'] }">
          <el-select v-model="listenerFieldForm.fieldType" placeholder="请选择字段类型" style="width:100%">
            <el-option v-for="i in Object.keys(fieldTypeObject)" :key="i" :label="fieldTypeObject[i]" :value="i" />
          </el-select>
        </el-form-item>
        <el-form-item
          v-if="listenerFieldForm.fieldType === 'string'"
          key="field-string"
          label="字段值："
          prop="string"
          :rules="{ required: true,message: '请填写字段值', trigger: ['blur', 'change'] }">
          <el-input v-model="listenerFieldForm.string" clearable placeholder="请填写字段值" />
        </el-form-item>
        <el-form-item
          v-if="listenerFieldForm.fieldType === 'expression'"
          key="field-expression"
          label="表达式："
          prop="expression"
          :rules="{ required: true,message:'请填写表达式', trigger: ['blur', 'change'] }">
          <el-input v-model="listenerFieldForm.expression" clearable placeholder="请填写表达式" />
        </el-form-item>
      </el-form>
      <template slot="footer">
        <el-button size="mini" @click="listenerFieldFormModelVisible = false">取 消</el-button>
        <el-button size="mini" type="primary" @click="saveListenerFiled">确 定</el-button>
      </template>
    </el-dialog>
  </div>
</template>
<script>
import { uuid, createListenerObject, updateElementExtensions } from '../../utils'
import { initListenerForm, initListenerType, eventType, listenerType, fieldType } from './utilSelf'

export default {
  name: 'UserTaskListeners',
  props: {
    id: {
      type: String,
      default: null
    },
    type: {
      type: String,
      default: null
    }
  },
  inject: {
    prefix: 'prefix',
    width: 'width'
  },
  data() {
    return {
      elementListenersList: [],
      listenerEventTypeObject: eventType,
      listenerTypeObject: listenerType,
      listenerFormModelVisible: false,
      listenerForm: {},
      fieldTypeObject: fieldType,
      fieldsListOfListener: [],
      listenerFieldFormModelVisible: false, // 监听器 注入字段表单弹窗 显示状态
      editingListenerIndex: -1, // 监听器所在下标，-1 为新增
      editingListenerFieldIndex: -1, // 字段所在下标，-1 为新增
      listenerFieldForm: {} // 监听器 注入字段 详情表单
    }
  },
  watch: {
    id: {
      immediate: true,
      handler(val) {
        val && val.length && this.$nextTick(() => this.resetListenersList())
      }
    }
  },
  methods: {
    handleClose(done) {
      this.$confirm('确认关闭？')
        .then(_ => {
          done()
        })
        .catch(_ => {})
    },
    resetListenersList() {
      this.bpmnElement = window.bpmnInstances.bpmnElement
      this.otherExtensionList = []
      this.bpmnElementListeners = []
      if (this.bpmnElement.businessObject) {
        if (this.bpmnElement.businessObject.extensionElements) {
          if (this.bpmnElement.businessObject.extensionElements.values) {
            this.bpmnElementListeners = this.bpmnElement.businessObject.extensionElements.values.filter(ex => ex.$type === `${this.prefix}:TaskListener`) ?? []
          }
        }
      }
      // this.bpmnElement.businessObject?.extensionElements?.values?.filter(ex => ex.$type === `${this.prefix}:TaskListener`) ?? [];
      this.elementListenersList = this.bpmnElementListeners.map(listener => initListenerType(listener))
    },
    openListenerForm(listener, index) {
      if (listener) {
        this.listenerForm = initListenerForm(listener)
        this.editingListenerIndex = index
      } else {
        this.listenerForm = {
          id: uuid()
        }
        this.editingListenerIndex = -1 // 标记为新增
      }
      if (listener && listener.fields) {
        this.fieldsListOfListener = listener.fields.map(field => ({ ...field, fieldType: field.string ? 'string' : 'expression' }))
      } else {
        this.fieldsListOfListener = []
        this.$set(this.listenerForm, 'fields', [])
      }
      // 打开侧边栏并清楚验证状态
      this.listenerFormModelVisible = true
      this.$nextTick(() => {
        if (this.$refs['listenerFormRef']) this.$refs['listenerFormRef'].clearValidate()
      })
    },
    // 移除监听器
    removeListener(listener, index) {
      this.$confirm('确认移除该监听器吗？', '提示', {
        confirmButtonText: '确 认',
        cancelButtonText: '取 消'
      })
        .then(() => {
          this.bpmnElementListeners.splice(index, 1)
          this.elementListenersList.splice(index, 1)
          updateElementExtensions(this.bpmnElement, this.otherExtensionList.concat(this.bpmnElementListeners))
        })
        .catch(() => console.info('操作取消'))
    },
    // 保存监听器
    async saveListenerConfig() {
      this.$refs['listenerFormRef'].validate(valid => {
        if (valid) {
          const listenerObject = createListenerObject(this.listenerForm, true, this.prefix)
          if (this.editingListenerIndex === -1) {
            this.bpmnElementListeners.push(listenerObject)
            this.elementListenersList.push(this.listenerForm)
          } else {
            this.bpmnElementListeners.splice(this.editingListenerIndex, 1, listenerObject)
            this.elementListenersList.splice(this.editingListenerIndex, 1, this.listenerForm)
          }
          // 保存其他配置
          this.otherExtensionList = []
          if (this.bpmnElement.businessObject) {
            if (this.bpmnElement.businessObject.extensionElements) {
              if (this.bpmnElement.businessObject.extensionElements.values) {
                this.otherExtensionList = this.bpmnElement.businessObject.extensionElements.values.filter(ex => ex.$type !== `${this.prefix}:TaskListener`) ?? []
              }
            }
          }
          // this.bpmnElement.businessObject?.extensionElements?.values?.filter(ex => ex.$type !== `${this.prefix}:TaskListener`) ?? [];
          updateElementExtensions(this.bpmnElement, this.otherExtensionList.concat(this.bpmnElementListeners))
          // 4. 隐藏侧边栏
          this.listenerFormModelVisible = false
          this.listenerForm = {}
        }
      })
    },
    // 打开监听器字段编辑弹窗
    openListenerFieldForm(field, index) {
      this.listenerFieldForm = field ? JSON.parse(JSON.stringify(field)) : {}
      this.editingListenerFieldIndex = field ? index : -1
      this.listenerFieldFormModelVisible = true
      this.$nextTick(() => {
        if (this.$refs['listenerFieldFormRef']) this.$refs['listenerFieldFormRef'].clearValidate()
      })
    },
    // 保存监听器注入字段
    async saveListenerFiled() {
      this.$refs['listenerFieldFormRef'].validate(valid => {
        if (valid) {
          if (this.editingListenerFieldIndex === -1) {
            this.fieldsListOfListener.push(this.listenerFieldForm)
            this.listenerForm.fields.push(this.listenerFieldForm)
          } else {
            this.fieldsListOfListener.splice(this.editingListenerFieldIndex, 1, this.listenerFieldForm)
            this.listenerForm.fields.splice(this.editingListenerFieldIndex, 1, this.listenerFieldForm)
          }
          this.listenerFieldFormModelVisible = false
          this.$nextTick(() => (this.listenerFieldForm = {}))
        }
      })
    },
    // 移除监听器字段
    removeListenerField(field, index) {
      this.$confirm('确认移除该字段吗？', '提示', {
        confirmButtonText: '确 认',
        cancelButtonText: '取 消'
      })
        .then(() => {
          this.fieldsListOfListener.splice(index, 1)
          this.listenerForm.fields.splice(index, 1)
        })
        .catch(() => console.info('操作取消'))
    }
  }
}
</script>
